﻿using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;
using System;
using System.IO;
using Message;
using System.Collections.Generic;

namespace Server.Net
{
    public class PlayerSession : AppSession<PlayerSession, BinaryRequestInfo>
    {
        public int uid = -1;
        public string uname;

        private bool isSending = false;
        private Queue<byte[]> sendCache = new Queue<byte[]>();

        public long lastTickTime = long.MinValue;

        public bool isUse = false;

        public float x;
        public float y;
        public float z;
        public float angle;

        protected override void HandleException(Exception e)
        {
            base.HandleException(e);
            Console.WriteLine(uid + "HandleException  " + e.ToString());
            Close();
        }

        /// <summary>
        /// 连接开始
        /// </summary>
        protected override void OnSessionStarted()
        {
            base.OnSessionStarted();
            isUse = true;
            lastTickTime = Sys.GetTimeStamp();
            Console.WriteLine(uid + "OnSessionStarted lastTickTime:" + lastTickTime);
        }

        public void Receive(string key, byte[] body)
        {
            //Console.WriteLine("处理消息 " + key);
            int protoId = Convert.ToInt32(key);
            Type protoType = ProtoDic.GetProtoTypeByProtoId(protoId);
            object toc = ProtoBuf.Serializer.Deserialize(protoType, new MemoryStream(body));
            //注册
            if (protoId == 1001)
            {
                C2SRegister ctsr = toc as C2SRegister;
                Console.WriteLine(ctsr.uname + " " + ctsr.pwd);

                S2CRegisterRet stcr = new S2CRegisterRet();
                if (DataMgr.Instance.Register(ctsr.uname, ctsr.pwd))
                {
                    stcr.code = 0;
                }
                else
                {
                    stcr.code = -1;
                }
                SendObj(stcr);
            }
            //登录
            if (protoId == 1003)
            {
                C2SLogin ctsl = toc as C2SLogin;
                Console.WriteLine(ctsl.uname + " " + ctsl.pwd);
                S2CLoginRet stcl = new S2CLoginRet();
                uid = DataMgr.Instance.CheckPassWord(ctsl.uname, ctsl.pwd);

                if (uid > -1)
                {
                    stcl.code = 0;
                    stcl.uid = uid;
                    if (!ServNet.instance.Users.ContainsKey(uid))
                    {
                        ServNet.instance.Users.Add(uid, this);
                    }
                    else
                    {
                        ServNet.instance.Users[uid].Close();
                        ServNet.instance.Users.Remove(uid);
                        ServNet.instance.Users.Add(uid, this);
                    }
                    uname = ctsl.uname;
                }
                else
                {
                    stcl.code = -1;
                }
                SendObj(stcl);
            }
            //心跳
            if (protoId == 1005)
            {
                lastTickTime = Sys.GetTimeStamp();
                S2CHeatBeat stshb = new S2CHeatBeat();
                TimeSpan ts = new TimeSpan(DateTime.Now.Ticks);
                stshb.time = (long)ts.TotalMilliseconds;
                SendObj(stshb);
                Console.WriteLine("收到心跳: 更新lastTickTime:" + lastTickTime);
            }
            //登出
            if (protoId == 1007)
            {
                C2SLogout stshb = toc as C2SLogout;
                Close();
                //SendObj(stshb); 
            }
            //消息
            if (protoId == 1009)
            {
                C2SChat ctsc = toc as C2SChat;
            }
            //添加好友
            if (protoId == 1011)
            {
                C2SAddFriend ctsc = toc as C2SAddFriend;
            }

            //同意或拒绝添加好友
            if (protoId == 1013)
            {
                C2SAddFriendRet ctsc = toc as C2SAddFriendRet;
            }

            //删除好友
            if (protoId == 1015)
            {
                C2SDelFriend ctsc = toc as C2SDelFriend;
            }

            //删除好友回馈
            if (protoId == 1017)
            {
                C2SDelFriendRet ctsc = toc as C2SDelFriendRet;
            }

            //获取在线玩家列表
            if (protoId == 1019)
            {
                C2SGetPlayerList ctsg = toc as C2SGetPlayerList;

                S2CGetPlayerList stcgl = new S2CGetPlayerList();

                foreach (KeyValuePair<int, PlayerSession> user in ServNet.instance.Users)
                {
                    Player p = new Player
                    {
                        uid = user.Value.uid,
                        uname = user.Value.uname
                    };
                    stcgl.players.Add(p);
                }
                SendObj(stcgl);
            }

            //玩家发过来的位置旋转数据
            if (protoId == 1021)
            {
                C2SMove ctsm = toc as C2SMove;
                x = ctsm.x;
                y = ctsm.y;
                z = ctsm.z;
                angle = ctsm.angle;
            }

            //创建角色
            if (protoId == 1023)
            {
                C2SCreatRole ctsr = toc as C2SCreatRole;

                S2CCreatRoleRet stcr = new S2CCreatRoleRet();
                if (DataMgr.Instance.CreatRole(ctsr.uid, ctsr.name, ctsr.type))
                {
                    stcr.code = 0;
                }
                else
                {
                    stcr.code = -1;
                }
                SendObj(stcr);
            }

            //获取角色列表
            if (protoId == 1027)
            {
                C2SGetRoles ctsg = toc as C2SGetRoles;
                List<Role> roles = DataMgr.Instance.GetRoles(ctsg.uid);
                S2CGetRolesRet stcg = new S2CGetRolesRet();
                foreach (Role role in roles)
                {
                    stcg.roles.Add(role);
                }
                SendObj(stcg);
            }
        }

        public void SendObj(object proto)
        {
            if (!isUse)
            {
                Console.WriteLine(uid + "SendObj  " + isUse);
                return;
            }

            if (!isSending)
            {
                byte[] data = NetCode.Encode(proto);
                sendCache.Enqueue(data);
                Send();
            }
        }

        private void Send()
        {
            try
            {
                if (sendCache.Count == 0)
                {
                    isSending = false;
                    return;
                }

                isSending = true;
                byte[] data = sendCache.Dequeue();
                Send(new ArraySegment<byte>(data));
                isSending = false;
                Send();
            }
            catch (Exception e)
            {
                Console.WriteLine("Send():" + e.Message);
            }
        }

        /// <summary>
        /// 连接断开
        /// </summary>
        /// <param name="reason"></param>
        protected override void OnSessionClosed(CloseReason reason)
        {
            base.OnSessionClosed(reason);
            isUse = false;
            Console.WriteLine(uid + "OnSessionClosed");
            if (ServNet.instance.Users.ContainsKey(uid))
            {
                ServNet.instance.Users.Remove(uid);
            }
        }
    }
}